<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Dictionary</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
  var popup = document.getElementById(material_id);
  popup.classList.toggle("show");
}
</script>

<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
MathJax = {
	tex: {
		inlineMath: '$', '$'], ['\\(', '\\)'
	},
	svg: {
		fontCache: 'global'
	}
};
</script>
<script type="text/javascript" id="MathJax-script" async
	src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>

<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html">
<img src="../docs-assets/Inform.png" height=72">
</a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../indocn.html">indoc</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
<li><a href="../inrtpsn.html">inrtps</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=18> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="../../../inweb/index.html">inweb</a></li>
<li><a href="../../../intest/index.html">intest</a></li>

</ul>
		</nav>
		<main role="main">
		<!--Weave of 'Dictionary' generated by Inweb-->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inbuildn.html">Inbuild Modules</a></li><li><a href="index.html">supervisor</a></li><li><a href="index.html#7">Chapter 7: Extension Indexing</a></li><li><b>Dictionary</b></li></ul></div>
<p class="purpose">To maintain a database of names and constructions in all extensions so far used by this installation of Inform, and spot potential namespace clashes.</p>

<ul class="toc"><li><a href="7-dct.html#SP1">&#167;1. The dictionary file</a></li><li><a href="7-dct.html#SP3">&#167;3. Storage in memory</a></li><li><a href="7-dct.html#SP8">&#167;8. Reading in</a></li><li><a href="7-dct.html#SP10">&#167;10. Writing out</a></li><li><a href="7-dct.html#SP11">&#167;11. Erasing entries</a></li><li><a href="7-dct.html#SP12">&#167;12. Sorting the extension dictionary</a></li><li><a href="7-dct.html#SP14">&#167;14. Writing the HTML extension index</a></li></ul><hr class="tocbar">

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. The dictionary file. </b>Each time an extension is successfully used, a dictionary of items defined in
the user's extensions is updated: this is used to generate the dynamic
documentation on installed extensions, and is stored between runs in a cache
file inside the Inform GUI applications. The dictionary is a UTF-8 encoded
text file, kept in the user's transient storage area. (It's no enormous
loss if this should be mislaid.)
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="function-syntax">ExtensionDictionary::filename</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">ExtensionDictionary::filename</span></span>:<br/><a href="7-dct.html#SP8">&#167;8</a>, <a href="7-dct.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><a href="1-ic.html#SP19" class="function-link"><span class="function-syntax">Supervisor::transient</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">P</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Pathnames::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Documentation"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Pathnames::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Census"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Dictionary.txt"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2.  </b>In December 2007, the dictionary file of a user who had employed 155 different
extensions (by 33 different authors) contained 2223 entries, the longest of
which formed a line 95 characters long: the most prolific extension made 380
definitions. The total file size was about 130K.
</p>

<p class="commentary">Typical dictionary file contents look like this. The four columns are author,
title, headword and category.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">...</span>
<span class="plain-syntax">|Emily Short|Plurality|20110130181823:Sun 30 January 2011 18:18|indexing|</span>
<span class="plain-syntax">|Emily Short|Plurality|prior named noun|value|</span>
<span class="plain-syntax">|Emily Short|Plurality|ambiguously plural|property|</span>
<span class="plain-syntax">|Emily Short|Plurality|ordinarily enumerated|property|</span>
<span class="plain-syntax">|Emily Short|Locksmith|20110130181823:Sun 30 January 2011 18:18|indexing|</span>
<span class="plain-syntax">|Emily Short|Locksmith|passkey|kind|</span>
<span class="plain-syntax">|Emily Short|Locksmith|keychain|kind|</span>
<span class="plain-syntax">...</span>
</pre>
<p class="commentary">It is not necessarily stored in a sorted form, and no ordering of lines is
guaranteed.
</p>

<p class="commentary">The special entries with category "indexing" have two roles: they are
markers that the extension in question is indexed in the dictionary, and
they record the last date on which the extension was used.
</p>

<p class="commentary">Note that the stroke character is illegal in unquoted Inform source text,
and therefore also in excerpts with meanings, in extension titles and in
author names. It can therefore safely be used as a field divider.
</p>

<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. Storage in memory. </b>Each record (i.e., line in the above file) is stored in memory thus. A
record marked "to be erased" will not be saved back to the file in due course.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">inform_extension</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ede_extension</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ede_work</span><span class="plain-syntax">; </span><span class="comment-syntax"> author name and title, with hash code</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">entry_text</span><span class="plain-syntax">; </span><span class="comment-syntax"> text of the dictionary entry</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">type</span><span class="plain-syntax">; </span><span class="comment-syntax"> grammatical category, such as "kind"</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">erased</span><span class="plain-syntax">; </span><span class="comment-syntax"> marked to be erased</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_in_sorted_dictionary</span><span class="plain-syntax">; </span><span class="comment-syntax"> temporary use only</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sorting</span><span class="plain-syntax">; </span><span class="comment-syntax"> temporary use only</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure extension_dictionary_entry is accessed in 3/bg, 3/ib, 5/ks, 7/ip, 7/tr and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4.  </b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ExtensionDictionary::new_ede</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">ExtensionDictionary::new_ede</span></span>:<br/><a href="7-dct.html#SP5">&#167;5</a>, <a href="7-dct.html#SP6">&#167;6</a>, <a href="7-dct.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inform_extension</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">category</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">author</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">title</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">headword</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">E</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no E for EDE"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ede</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ede_extension</span><span class="plain-syntax"> = </span><span class="identifier-syntax">E</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ede_work</span><span class="plain-syntax"> = </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_copy</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">edition</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">work</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">entry_text</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">headword</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">type</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">category</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sorting</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::new</span><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_wide_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">category</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"indexing"</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="7-dct.html#SP4_1" class="named-paragraph-link"><span class="named-paragraph">Change the sort and usage dates, and word count, for the extension work</span><span class="named-paragraph-number">4.1</span></a></span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">has_historically_been_used</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">erased</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_in_sorted_dictionary</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">EXTENSIONS_CENSUS</span><span class="plain-syntax">, </span><span class="string-syntax">"Created $d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">ede</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4_1" class="paragraph-anchor"></a><b>&#167;4.1.  </b>Data on, for example, when an extension was last used is cached in <span class="extract"><span class="extract-syntax">indexing</span></span>
records in the dictionary file. When we generate such an EDE, we must have
new information on those, so we update the <a href="2-wrk.html#SP1" class="internal">inbuild_work</a> object representing
the extension:
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Change the sort and usage dates, and word count, for the extension work</span><span class="named-paragraph-number">4.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">sdate</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">udate</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">wc</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">entry_text</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::get</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">) == </span><span class="character-syntax">'/'</span><span class="plain-syntax">) { </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::get</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">) == </span><span class="character-syntax">':'</span><span class="plain-syntax">) { </span><span class="identifier-syntax">mode</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">; </span><span class="reserved-syntax">continue</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">digital</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Characters::isdigit</span><span class="plain-syntax">(</span><span class="identifier-syntax">Str::get</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">));</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mode</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">: </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">digital</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">sdate</span><span class="plain-syntax">, </span><span class="identifier-syntax">Str::get</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">));</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">: </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">digital</span><span class="plain-syntax">) </span><span class="identifier-syntax">wc</span><span class="plain-syntax"> = </span><span class="constant-syntax">10</span><span class="plain-syntax">*</span><span class="identifier-syntax">wc</span><span class="plain-syntax"> + ((</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">Str::get</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">)) - ((</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="character-syntax">'0'</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">: </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">udate</span><span class="plain-syntax">, </span><span class="identifier-syntax">Str::get</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">));</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">sdate</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><a href="5-es.html#SP5" class="function-link"><span class="function-syntax">Extensions::set_sort_date</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ede_extension</span><span class="plain-syntax">, </span><span class="identifier-syntax">sdate</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wc</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><a href="5-es.html#SP5" class="function-link"><span class="function-syntax">Extensions::set_word_count</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ede_extension</span><span class="plain-syntax">, </span><span class="identifier-syntax">wc</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">udate</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><a href="5-es.html#SP5" class="function-link"><span class="function-syntax">Extensions::set_usage_date</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ede_extension</span><span class="plain-syntax">, </span><span class="identifier-syntax">udate</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">sdate</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">udate</span><span class="plain-syntax">)</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="7-dct.html#SP4">&#167;4</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5.  </b>This is where the <span class="extract"><span class="extract-syntax">indexing</span></span> records are made; they time-stamp the extension
with its time of last usage, and the word count. (<span class="extract"><span class="extract-syntax">the_present</span></span> is a global
variable created by <a href="../../../inweb/foundation-module/index.html" class="internal">foundation</a>.)
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ExtensionDictionary::time_stamp</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">ExtensionDictionary::time_stamp</span></span>:<br/>The Mini-Website - <a href="7-tm.html#SP2_1">&#167;2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inform_extension</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">dbuff</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ascday</span><span class="plain-syntax">[] = { </span><span class="string-syntax">"Sun"</span><span class="plain-syntax">, </span><span class="string-syntax">"Mon"</span><span class="plain-syntax">, </span><span class="string-syntax">"Tue"</span><span class="plain-syntax">, </span><span class="string-syntax">"Wed"</span><span class="plain-syntax">, </span><span class="string-syntax">"Thu"</span><span class="plain-syntax">, </span><span class="string-syntax">"Fri"</span><span class="plain-syntax">, </span><span class="string-syntax">"Sat"</span><span class="plain-syntax"> };</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ascmon</span><span class="plain-syntax">[] = { </span><span class="string-syntax">"January"</span><span class="plain-syntax">, </span><span class="string-syntax">"February"</span><span class="plain-syntax">, </span><span class="string-syntax">"March"</span><span class="plain-syntax">, </span><span class="string-syntax">"April"</span><span class="plain-syntax">, </span><span class="string-syntax">"May"</span><span class="plain-syntax">, </span><span class="string-syntax">"June"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="string-syntax">"July"</span><span class="plain-syntax">, </span><span class="string-syntax">"August"</span><span class="plain-syntax">, </span><span class="string-syntax">"September"</span><span class="plain-syntax">, </span><span class="string-syntax">"October"</span><span class="plain-syntax">, </span><span class="string-syntax">"November"</span><span class="plain-syntax">, </span><span class="string-syntax">"December"</span><span class="plain-syntax"> };</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">dbuff</span><span class="plain-syntax">, </span><span class="string-syntax">"%04d%02d%02d%02d%02d%02d/%d:%s %d %s %d %02d:%02d"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">the_present</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">tm_year</span><span class="plain-syntax">+1900, </span><span class="identifier-syntax">the_present</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">tm_mon</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">the_present</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">tm_mday</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">the_present</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">tm_hour</span><span class="plain-syntax">, </span><span class="identifier-syntax">the_present</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">tm_min</span><span class="plain-syntax">, </span><span class="identifier-syntax">the_present</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">tm_sec</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">read_into_file</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">TextFromFiles::total_word_count</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">read_into_file</span><span class="plain-syntax">)):0,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">ascday</span><span class="plain-syntax">[</span><span class="identifier-syntax">the_present</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">tm_wday</span><span class="plain-syntax">], </span><span class="identifier-syntax">the_present</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">tm_mday</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">ascmon</span><span class="plain-syntax">[</span><span class="identifier-syntax">the_present</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">tm_mon</span><span class="plain-syntax">], </span><span class="identifier-syntax">the_present</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">tm_year</span><span class="plain-syntax">+1900,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">the_present</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">tm_hour</span><span class="plain-syntax">, </span><span class="identifier-syntax">the_present</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">tm_min</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="7-dct.html#SP4" class="function-link"><span class="function-syntax">ExtensionDictionary::new_ede</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"indexing"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">as_copy</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">edition</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">author_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_copy</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">edition</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">title</span><span class="plain-syntax">, </span><span class="identifier-syntax">dbuff</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">dbuff</span><span class="plain-syntax">)</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6.  </b>We provide two more convenient creator functions: from a wording or from text.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ExtensionDictionary::new_entry_from_wording</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">category</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inform_extension</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)) { </span><span class="comment-syntax"> a safety precaution: never index the empty text</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">headword</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">headword</span><span class="plain-syntax">, </span><span class="string-syntax">"%+W"</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="7-dct.html#SP6" class="function-link"><span class="function-syntax">ExtensionDictionary::new_entry</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">category</span><span class="plain-syntax">, </span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">headword</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">headword</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ExtensionDictionary::new_entry</span><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">category</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inform_extension</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">headword</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><a href="7-dct.html#SP4" class="function-link"><span class="function-syntax">ExtensionDictionary::new_ede</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">, </span><span class="identifier-syntax">category</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">as_copy</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">edition</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">author_name</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">as_copy</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">edition</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">title</span><span class="plain-syntax">, </span><span class="identifier-syntax">headword</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7.  </b>The following logs the dictionary, and looks roughly like the file records,
but note that it lists the erasure flag too:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ExtensionDictionary::log_entry</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">ExtensionDictionary::log_entry</span></span>:<br/>Supervisor Module - <a href="1-sm.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ede</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"ede: %05d %d |%S|%S|%S|%S|\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">erased</span><span class="plain-syntax">, </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ede_work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">author_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ede_work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">title</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">entry_text</span><span class="plain-syntax">, </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">type</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. Reading in. </b>Not a surprising function: open, convert one line at a time to an
<a href="7-dct.html#SP3" class="internal">extension_dictionary_entry</a> object, close.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ExtensionDictionary::read_from_file</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">ExtensionDictionary::read_from_file</span></span>:<br/>The Mini-Website - <a href="7-tm.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax"> = </span><a href="7-dct.html#SP1" class="function-link"><span class="function-syntax">ExtensionDictionary::filename</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">F</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="7-dct.html#SP8_1" class="named-paragraph-link"><span class="named-paragraph">Ensure the serialised extensions dictionary file exists</span><span class="named-paragraph-number">8.1</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">EXTENSIONS_CENSUS</span><span class="plain-syntax">, </span><span class="string-syntax">"Reading dictionary file %f\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TextFiles::read</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><a href="7-dct.html#SP9" class="function-link"><span class="function-syntax">ExtensionDictionary::load_helper</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">EXTENSIONS_CENSUS</span><span class="plain-syntax">, </span><span class="string-syntax">"Finished reading dictionary file\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_1" class="paragraph-anchor"></a><b>&#167;8.1.  </b>The extension dictionary file is stored only transiently and may never have
been made, or may have been wiped by a zealous mobile OS. If it doesn't exist,
we try to make an empty one. Should these attempts fail, we simply return:
there might be permissions reasons, and it doesn't matter too much.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Ensure the serialised extensions dictionary file exists</span><span class="named-paragraph-number">8.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">DICTF</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::fopen</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="string-syntax">"r"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DICTF</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">EXTENSIONS_CENSUS</span><span class="plain-syntax">, </span><span class="string-syntax">"Creating new empty dictionary file\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">EMPTY_DICTF</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::fopen</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="string-syntax">"w"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">EMPTY_DICTF</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">fclose</span><span class="plain-syntax">(</span><span class="identifier-syntax">EMPTY_DICTF</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="7-dct.html#SP8">&#167;8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9.  </b>We parse lines in a fairly forgiving way. Material before the initial stroke
is ignored; material after the final stroke is also ignored, and any line not
containing five vertical strokes (i.e., four stroke-divided fields) is ignored
altogether. We're being forgiving in case the user has picked up Inform again
after ten years away, and still has an old dictionary file from the bad old
days when overlong records were truncated.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ExtensionDictionary::load_helper</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">ExtensionDictionary::load_helper</span></span>:<br/><a href="7-dct.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">line_entry</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">state</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">author</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">title</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">headword</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">category</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">strokes</span><span class="plain-syntax">, </span><span class="identifier-syntax">pos</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">strokes</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">pos</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">strokes</span><span class="plain-syntax"> &lt;= </span><span class="constant-syntax">5</span><span class="plain-syntax">; </span><span class="identifier-syntax">pos</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::get_at</span><span class="plain-syntax">(</span><span class="identifier-syntax">line_entry</span><span class="plain-syntax">, </span><span class="identifier-syntax">pos</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'|'</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">strokes</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">5</span><span class="plain-syntax">) </span><span class="identifier-syntax">strokes</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">        } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">strokes</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">: </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">author</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">: </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">title</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax">: </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">headword</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax">: </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">category</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax">: </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">author</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">title</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">headword</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">category</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">inbuild_requirement</span><span class="plain-syntax"> *</span><span class="identifier-syntax">req</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">            </span><a href="2-rqr.html#SP2" class="function-link"><span class="function-syntax">Requirements::any_version_of</span></a><span class="plain-syntax">(</span><a href="2-wrk.html#SP2" class="function-link"><span class="function-syntax">Works::new</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">extension_genre</span><span class="plain-syntax">, </span><span class="identifier-syntax">title</span><span class="plain-syntax">, </span><span class="identifier-syntax">author</span><span class="plain-syntax">));</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">inbuild_search_result</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">            </span><a href="2-nst.html#SP10" class="function-link"><span class="function-syntax">Nests::search_for_best</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">req</span><span class="plain-syntax">, </span><a href="1-ic.html#SP16" class="function-link"><span class="function-syntax">Supervisor::shared_nest_list</span></a><span class="plain-syntax">());</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax">) </span><a href="7-dct.html#SP4" class="function-link"><span class="function-syntax">ExtensionDictionary::new_ede</span></a><span class="plain-syntax">(</span><a href="5-es.html#SP4" class="function-link"><span class="function-syntax">Extensions::from_copy</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">copy</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">category</span><span class="plain-syntax">, </span><span class="identifier-syntax">author</span><span class="plain-syntax">, </span><span class="identifier-syntax">title</span><span class="plain-syntax">, </span><span class="identifier-syntax">headword</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::from_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">at</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">inbuild_copy</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax"> = </span><a href="4-em.html#SP5" class="function-link"><span class="function-syntax">ExtensionManager::claim_file_as_copy</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C</span><span class="plain-syntax">) </span><a href="7-dct.html#SP4" class="function-link"><span class="function-syntax">ExtensionDictionary::new_ede</span></a><span class="plain-syntax">(</span><a href="5-es.html#SP4" class="function-link"><span class="function-syntax">Extensions::from_copy</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">),</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">category</span><span class="plain-syntax">, </span><span class="identifier-syntax">author</span><span class="plain-syntax">, </span><span class="identifier-syntax">title</span><span class="plain-syntax">, </span><span class="identifier-syntax">headword</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. Writing out. </b>And inversely... Note that erased records are not written.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ExtensionDictionary::write_back</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">ExtensionDictionary::write_back</span></span>:<br/>The Mini-Website - <a href="7-tm.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> </span><span class="identifier-syntax">DICTF_struct</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">DICTF</span><span class="plain-syntax"> = &amp;</span><span class="identifier-syntax">DICTF_struct</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax"> = </span><a href="7-dct.html#SP1" class="function-link"><span class="function-syntax">ExtensionDictionary::filename</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">F</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">STREAM_OPEN_TO_FILE</span><span class="plain-syntax">(</span><span class="identifier-syntax">DICTF</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">UTF8_ENC</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="7-dct.html#SP10_1" class="named-paragraph-link"><span class="named-paragraph">Write into DICTF</span><span class="named-paragraph-number">10.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">STREAM_CLOSE</span><span class="plain-syntax">(</span><span class="identifier-syntax">DICTF</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10_1" class="paragraph-anchor"></a><b>&#167;10.1.  </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Write into DICTF</span><span class="named-paragraph-number">10.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">EXTENSIONS_CENSUS</span><span class="plain-syntax">, </span><span class="string-syntax">"Writing dictionary file\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ede</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">ede</span><span class="plain-syntax">, </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">erased</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">EXTENSIONS_CENSUS</span><span class="plain-syntax">, </span><span class="string-syntax">"Writing $d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">ede</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">DICTF</span><span class="plain-syntax">, </span><span class="string-syntax">"|%S|%S|%S|%S|%f\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ede_work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">author_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ede_work</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">title</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">entry_text</span><span class="plain-syntax">, </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">type</span><span class="plain-syntax">, </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ede_extension</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_copy</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">location_if_file</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">EXTENSIONS_CENSUS</span><span class="plain-syntax">, </span><span class="string-syntax">"Suppressing $d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">ede</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">EXTENSIONS_CENSUS</span><span class="plain-syntax">, </span><span class="string-syntax">"Finished writing dictionary file\n"</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="7-dct.html#SP10">&#167;10</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. Erasing entries. </b>As noted above, any entry marked <span class="extract"><span class="extract-syntax">erased</span></span> is not written back to the
dictionary file, and effectively that takes it out of the dictionary for
subsequent runs of Inform.
</p>

<p class="commentary">This arises when we are making the dictionary entries for an extension which
was used on the current run. Before making new entries, we erase all entries
left over from some previous usage of it: it may, after all, have changed.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ExtensionDictionary::erase_entries_concerning</span><span class="plain-syntax">(</span><span class="reserved-syntax">inform_extension</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ede</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">EXTENSIONS_CENSUS</span><span class="plain-syntax">, </span><span class="string-syntax">"Erasure of dictionary entries for %X\n"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">as_copy</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">edition</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">work</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">ede</span><span class="plain-syntax">, </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">erased</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">            (</span><a href="2-wrk.html#SP9" class="function-link"><span class="function-syntax">Works::match</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ede_work</span><span class="plain-syntax">, </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_copy</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">edition</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">work</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">erased</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">EXTENSIONS_CENSUS</span><span class="plain-syntax">, </span><span class="string-syntax">"Erased $d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">ede</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">EXTENSIONS_CENSUS</span><span class="plain-syntax">, </span><span class="string-syntax">"Done\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. Sorting the extension dictionary. </b>This function returns the number of (unerased) entries in the dictionary,
and on its exit the (unerased) entries each occur once in alphabetical
order in the linked list beginning at <span class="extract"><span class="extract-syntax">first_in_sorted_dictionary</span></span>.
If two entries have identical headwords, the earliest created is the
one which appears earlier in the sorted dictionary.
</p>

<p class="commentary">We pass this job on to the standard C library <span class="extract"><span class="extract-syntax">qsort</span></span>, in hopes that it is
reasonably efficiently implemented: we certainly don't want to use an
algorithm likely to have \(O(n^2)\) running time, given that \(n\) is plausibly
as high as 10,000.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">first_in_sorted_dictionary</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>

<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">ExtensionDictionary::sort_extension_dictionary</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">ExtensionDictionary::sort_extension_dictionary</span></span>:<br/><a href="7-dct.html#SP14">&#167;14</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">EXTENSIONS_CENSUS</span><span class="plain-syntax">, </span><span class="string-syntax">"Beginning dictionary sort\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_entries</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">first_in_sorted_dictionary</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="7-dct.html#SP12_1" class="named-paragraph-link"><span class="named-paragraph">Count headwords and reprocess their texts for dictionary sorting</span><span class="named-paragraph-number">12.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">no_entries</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> **</span><span class="identifier-syntax">sorted_extension_dictionary</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Memory::calloc</span><span class="plain-syntax">(</span><span class="identifier-syntax">no_entries</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> *), </span><span class="constant-syntax">EXTENSION_DICTIONARY_MREASON</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="7-dct.html#SP12_2" class="named-paragraph-link"><span class="named-paragraph">Fill the array with pointers to the EDEs</span><span class="named-paragraph-number">12.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">qsort</span><span class="plain-syntax">(</span><span class="identifier-syntax">sorted_extension_dictionary</span><span class="plain-syntax">, (</span><span class="identifier-syntax">size_t</span><span class="plain-syntax">) </span><span class="identifier-syntax">no_entries</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> *),</span>
<span class="plain-syntax">        </span><a href="7-dct.html#SP13" class="function-link"><span class="function-syntax">ExtensionDictionary::compare_ed_entries</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="7-dct.html#SP12_3" class="named-paragraph-link"><span class="named-paragraph">String the sorted array together into a sorted linked list of EDEs</span><span class="named-paragraph-number">12.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Memory::I7_array_free</span><span class="plain-syntax">(</span><span class="identifier-syntax">sorted_extension_dictionary</span><span class="plain-syntax">, </span><span class="constant-syntax">EXTENSION_DICTIONARY_MREASON</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">no_entries</span><span class="plain-syntax">, </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> *));</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">EXTENSIONS_CENSUS</span><span class="plain-syntax">, </span><span class="string-syntax">"Sorted dictionary: %d entries\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">no_entries</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_entries</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12_1" class="paragraph-anchor"></a><b>&#167;12.1.  </b>Dictionary entries must be in mixed case: we might have both "green" the
colour and "Green" the kind of person (an environmental activist), say.
But we want to compare them with <span class="extract"><span class="extract-syntax">strcmp</span></span>, which is much faster than its
case-insensitive analogue. So we trade memory for speed and store a modified
form of the headword in which spaces are removed and letters are reduced
to lower case; note that this is no larger than the original, so there is
no risk of the <span class="extract"><span class="extract-syntax">sorting</span></span> string (which is 10 characters longer than the
unprocessed version) overflowing. Note: later we shall rely on the first
character of the sorting text being the lower-case form of the first
character of the original word.
</p>

<p class="commentary">We then append the allocation ID number, padded with initial zeros. We do
this so that (i) all sorting texts will be distinct, and (ii) alphabetical
order for sorting texts derived from two identical headword texts will
correspond to creation order. This ensures that <span class="extract"><span class="extract-syntax">qsort</span></span>'s output will be
predictable &mdash; implementations of Quicksort do not otherwise guarantee this,
since implementations have the freedom to sort unstably in different ways.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Count headwords and reprocess their texts for dictionary sorting</span><span class="named-paragraph-number">12.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ede</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">ede</span><span class="plain-syntax">, </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">erased</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">no_entries</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Str::clear</span><span class="plain-syntax">(</span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sorting</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">entry_text</span><span class="plain-syntax">)</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::get</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">) != </span><span class="character-syntax">' '</span><span class="plain-syntax">)</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sorting</span><span class="plain-syntax">,</span>
<span class="plain-syntax">                        </span><span class="identifier-syntax">Characters::tolower</span><span class="plain-syntax">(</span><span class="identifier-syntax">Str::get</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">)));</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sorting</span><span class="plain-syntax">, </span><span class="string-syntax">"-%09d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">EXTENSIONS_CENSUS</span><span class="plain-syntax">, </span><span class="string-syntax">"Sorted under '%S': $d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sorting</span><span class="plain-syntax">, </span><span class="identifier-syntax">ede</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="7-dct.html#SP12">&#167;12</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP12_2" class="paragraph-anchor"></a><b>&#167;12.2.  </b>We unbundle the linked list of EDEs in creation order:
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Fill the array with pointers to the EDEs</span><span class="named-paragraph-number">12.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ede</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">ede</span><span class="plain-syntax">, </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">erased</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">sorted_extension_dictionary</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">ede</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="7-dct.html#SP12">&#167;12</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP12_3" class="paragraph-anchor"></a><b>&#167;12.3.  </b>We then use the sorted version of the same array to reorder the EDEs:
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">String the sorted array together into a sorted linked list of EDEs</span><span class="named-paragraph-number">12.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">first_in_sorted_dictionary</span><span class="plain-syntax"> = </span><span class="identifier-syntax">sorted_extension_dictionary</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">no_entries</span><span class="plain-syntax">-1; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">sorted_extension_dictionary</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]-&gt;</span><span class="element-syntax">next_in_sorted_dictionary</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">sorted_extension_dictionary</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">+1];</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">no_entries</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">sorted_extension_dictionary</span><span class="plain-syntax">[</span><span class="identifier-syntax">no_entries</span><span class="plain-syntax">-1]-&gt;</span><span class="element-syntax">next_in_sorted_dictionary</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="7-dct.html#SP12">&#167;12</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13.  </b>As always with <span class="extract"><span class="extract-syntax">qsort</span></span>, there's a palaver about the types used for the
comparison function so that the result will compile without errors:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">ExtensionDictionary::compare_ed_entries</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">ExtensionDictionary::compare_ed_entries</span></span>:<br/><a href="7-dct.html#SP12">&#167;12</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">elem1</span><span class="plain-syntax">, </span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">elem2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> **</span><span class="identifier-syntax">e1</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> **) </span><span class="identifier-syntax">elem1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> **</span><span class="identifier-syntax">e2</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> **) </span><span class="identifier-syntax">elem2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((*</span><span class="identifier-syntax">e1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (*</span><span class="identifier-syntax">e2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"Disaster while sorting extension dictionary"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">Str::cmp</span><span class="plain-syntax">((*</span><span class="identifier-syntax">e1</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">sorting</span><span class="plain-syntax">, (*</span><span class="identifier-syntax">e2</span><span class="plain-syntax">)-&gt;</span><span class="element-syntax">sorting</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. Writing the HTML extension index. </b>This is the index of terms, not the directory of extensions: it is, in
fact, the HTML rendering of the dictionary constructed above.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ExtensionDictionary::write_to_HTML</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><a href="7-dct.html#SP12" class="function-link"><span class="function-syntax">ExtensionDictionary::sort_extension_dictionary</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">n</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">first_letter</span><span class="plain-syntax"> = </span><span class="character-syntax">'a'</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">previous_ede</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">,</span>
<span class="plain-syntax">            *</span><span class="identifier-syntax">ede</span><span class="plain-syntax"> = </span><span class="identifier-syntax">first_in_sorted_dictionary</span><span class="plain-syntax">; </span><span class="identifier-syntax">ede</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">previous_ede</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ede</span><span class="plain-syntax">, </span><span class="identifier-syntax">ede</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_in_sorted_dictionary</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::eq_wide_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">type</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"indexing"</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_ede</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_in_sorted_dictionary</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">this_first</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Characters::tolower</span><span class="plain-syntax">(</span><span class="identifier-syntax">Str::get_first_char</span><span class="plain-syntax">(</span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">entry_text</span><span class="plain-syntax">));</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">first_letter</span><span class="plain-syntax"> != </span><span class="identifier-syntax">this_first</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">HTML_TAG</span><span class="plain-syntax">(</span><span class="string-syntax">"br"</span><span class="plain-syntax">); </span><span class="identifier-syntax">first_letter</span><span class="plain-syntax"> = </span><span class="identifier-syntax">this_first</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">            </span><span class="named-paragraph-container code-font"><a href="7-dct.html#SP14_1" class="named-paragraph-link"><span class="named-paragraph">Write extension dictionary entry for this headword</span><span class="named-paragraph-number">14.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><a href="7-dct.html#SP18" class="function-link"><span class="function-syntax">ExtensionDictionary::list_known_extension_clashes</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP14_1" class="paragraph-anchor"></a><b>&#167;14.1.  </b>A run of \(N\) words which are all the same should appear in tinted type
throughout, while \(N(N-1)/2\) clashes should be reported to the machinery for
clashes given above: if we find definitions A, B, C, for instance, the clashes
are reported as A vs B, A vs C, then B vs C. This has \(O(N^2)\) running time,
so if there are 1000 extensions, each of which gives 1000 different meanings
to the word "frog", we would be in some trouble here. Let's take the risk.
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">EDES_DEFINE_SAME_WORD</span><span class="plain-syntax">(</span><span class="identifier-syntax">X</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y</span><span class="plain-syntax">) ((</span><span class="identifier-syntax">X</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Y</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">Str::eq</span><span class="plain-syntax">(</span><span class="identifier-syntax">X</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sorting</span><span class="plain-syntax">, </span><span class="identifier-syntax">Y</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sorting</span><span class="plain-syntax">)))</span>
</pre>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Write extension dictionary entry for this headword</span><span class="named-paragraph-number">14.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">tint</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">EDES_DEFINE_SAME_WORD</span><span class="plain-syntax">(</span><span class="identifier-syntax">ede</span><span class="plain-syntax">, </span><span class="identifier-syntax">previous_ede</span><span class="plain-syntax">)) </span><span class="identifier-syntax">tint</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">EDES_DEFINE_SAME_WORD</span><span class="plain-syntax">(</span><span class="identifier-syntax">ede</span><span class="plain-syntax">, </span><span class="identifier-syntax">next_ede</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">tint</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><a href="7-dct.html#SP17" class="function-link"><span class="function-syntax">ExtensionDictionary::extension_clash</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ede</span><span class="plain-syntax">, </span><span class="identifier-syntax">next_ede</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">next_ede</span><span class="plain-syntax"> = </span><span class="identifier-syntax">next_ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_in_sorted_dictionary</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HTML_OPEN_WITH</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">, </span><span class="string-syntax">"style='margin:0px; padding:0px;'"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tint</span><span class="plain-syntax">) </span><span class="identifier-syntax">HTML::begin_span</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"extensionindexerror"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">entry_text</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tint</span><span class="plain-syntax">) </span><span class="identifier-syntax">HTML::end_span</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" - &lt;i&gt;%S&lt;/i&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">type</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HTML::begin_span</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"smaller"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-wrk.html#SP7" class="function-link"><span class="function-syntax">Works::write_link_to_HTML_file</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">ede</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ede_work</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HTML::end_span</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="7-dct.html#SP14">&#167;14</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15.  </b>So, then, "clashes". These occur if, say, two extensions define "chopper" as
a kind of vehicle (for instance, meaning a helicopter in one and a motorcycle
in the other). This results in two dictionary entries under "chopper" and is
recorded as a clash between them. Often, more will turn up: perhaps "chopper"
might elsewhere mean a butchery tool. In the event of 3 or more clashing
entries, \(A, B, C, ...\), a linked list of ordered pairs \((A,B), (A,C), ...\) is
maintained where in each pair the first term (the left one) is from an
extension lexicographically earlier than the second (the right one).
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">known_extension_clash</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">first_known</span><span class="plain-syntax">; </span><span class="comment-syntax"> heads a linked list of clashes with a given </span><span class="extract"><span class="extract-syntax">ede1</span></span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">known_extension_clash</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next</span><span class="plain-syntax">; </span><span class="comment-syntax"> next in linked list of clashes</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">leftx</span><span class="plain-syntax">; </span><span class="comment-syntax"> clash is between this entry...</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rightx</span><span class="plain-syntax">; </span><span class="comment-syntax"> ...and this one</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">number_clashes</span><span class="plain-syntax">; </span><span class="comment-syntax"> number of entries clashing between </span><span class="extract"><span class="extract-syntax">ede1</span></span><span class="comment-syntax"> and </span><span class="extract"><span class="extract-syntax">ede2</span></span>
<span class="plain-syntax">    </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">known_extension_clash</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure known_extension_clash is accessed in 6/hdn, 6/inc, 7/cns and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16.  </b></p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">known_extension_clash</span><span class="plain-syntax"> *</span><span class="function-syntax">ExtensionDictionary::new_clash</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">ExtensionDictionary::new_clash</span></span>:<br/><a href="7-dct.html#SP17">&#167;17</a>, <a href="7-dct.html#SP17_2">&#167;17.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">first_known_flag</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">known_extension_clash</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kec</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">known_extension_clash</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">kec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">leftx</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">kec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">rightx</span><span class="plain-syntax"> = </span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">kec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">number_clashes</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">kec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_known</span><span class="plain-syntax"> = </span><span class="identifier-syntax">first_known_flag</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">kec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">kec</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17.  </b>Every clash of names arises from definitions made in a pair of EDEs,
which we shall call left and right. Each distinct KEC ("known extension
clash") represents a different pair of extensions which clash, one
example of a name clashing between them, and a count of the number of
such names.
</p>

<ul class="items"><li>(a) Given a pair of extensions, the left one is the one whose author name
followed by title is lexicographically earlier. Since we are only concerned
with clashes between different extensions, this unambiguously decides which
is leftmost, as title and author suffice to identify extensions.
</li><li>(b) Similarly, given a pair of EDEs, the left one is the one whose definition
arises from the lefthand extension. (So, for instance, any definition made
in one of Eric Eve's extensions is always to the left of any definition in
one of John Clemens's.) Different EDEs deriving from the same extension do
not exemplify a clash.
</li><li>(c) For each extension L, there is at most one KEC whose left EDE derives
from L and which has the "first known" flag set.
If such a KEC does not exist, then L does not clash with any other
extension.
If such a KEC does exist, then it is the head of a linked list of
KECs all of which have lefthand EDE deriving from L, and in which no two
entries have righthand EDEs deriving from the same extension as each other.
</li></ul>
<p class="commentary">It follows that we can determine if extensions X and Y clash by arranging
them as L and R (rule (a)), looking for L among the left EDEs of all KECs
with the "first known" flag set (rule (c)), and then looking for Y among
the right EDEs of all KECs in the list which hangs from that (rule (c.2)).
Should either of these searches fail, there is no clash between X and Y.
Should both succeed, then the KEC found provides a single example of the
clash (in its left and right EDEs), together with the number of clashes.
</p>

<p class="commentary">If there are \(n\) extensions then there could in theory be \(n(n-1)/2\) KECs,
which might amount to a lot of storage. In practice, though, Inform source
text tends to be dispersed around the cloud of English nouns and adjectives
fairly well, and since extension authors use each other's extensions, there
is also some social pressure to reduce the number of clashes. The user
mentioned above who had installed 155 different extensions &mdash; for a possible
11,935 distinct clashing pairs &mdash; in fact observed 15 such pairs, mostly arising
from part-finished drafts which had borrowed source text from pieces of other
extensions. Of the few remaining, several were cases where the same name
occurred in rival extensions aspiring to do much the same thing as each
other: for instance, "current quip" was defined by two different conversation
extensions. The only clashes of different meanings which might both be needed,
and which seem to have arisen spontaneously, were from definitions of the
words "seen" and "implicit", both treacherously ambiguous. Clashes did
not seem to have arisen from homonyms like "lead" (the substance) versus
"lead" (the cable to a pair of headphones).
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ExtensionDictionary::extension_clash</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">ExtensionDictionary::extension_clash</span></span>:<br/><a href="7-dct.html#SP14_1">&#167;14.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ede1</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ede2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">extension_dictionary_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">left</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">right</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inbuild_work</span><span class="plain-syntax"> *</span><span class="identifier-syntax">leftx</span><span class="plain-syntax">, *</span><span class="identifier-syntax">rightx</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">known_extension_clash</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kec</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">ede1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">ede2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"bad extension clash"</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">d</span><span class="plain-syntax"> = </span><a href="2-wrk.html#SP10" class="function-link"><span class="function-syntax">Works::cmp</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ede1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ede_work</span><span class="plain-syntax">, </span><span class="identifier-syntax">ede2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ede_work</span><span class="plain-syntax">); </span><span class="comment-syntax"> compare source extensions</span>

<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="7-dct.html#SP17_1" class="named-paragraph-link"><span class="named-paragraph">Ignore apparent clashes which are in fact not troublesome</span><span class="named-paragraph-number">17.1</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">d</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">left</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ede1</span><span class="plain-syntax">; </span><span class="identifier-syntax">right</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ede2</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">d</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">left</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ede2</span><span class="plain-syntax">; </span><span class="identifier-syntax">right</span><span class="plain-syntax"> = </span><span class="identifier-syntax">ede1</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">leftx</span><span class="plain-syntax"> = </span><span class="identifier-syntax">left</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ede_work</span><span class="plain-syntax">; </span><span class="identifier-syntax">rightx</span><span class="plain-syntax"> = </span><span class="identifier-syntax">right</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ede_work</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">kec</span><span class="plain-syntax">, </span><span class="reserved-syntax">known_extension_clash</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">kec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_known</span><span class="plain-syntax">) &amp;&amp; (</span><a href="2-wrk.html#SP9" class="function-link"><span class="function-syntax">Works::match</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">leftx</span><span class="plain-syntax">, </span><span class="identifier-syntax">kec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">leftx</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ede_work</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax">            </span><span class="named-paragraph-container code-font"><a href="7-dct.html#SP17_2" class="named-paragraph-link"><span class="named-paragraph">Search list of KECs deriving from the same left extension as this clash</span><span class="named-paragraph-number">17.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">kec</span><span class="plain-syntax"> = </span><a href="7-dct.html#SP16" class="function-link"><span class="function-syntax">ExtensionDictionary::new_clash</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">left</span><span class="plain-syntax">, </span><span class="identifier-syntax">right</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP17_1" class="paragraph-anchor"></a><b>&#167;17.1.  </b>If two name clashes occur in the same extension then, since we can presume
that this extension does actually work, the clash cannot cause problems.
We also ignore a clash of a property name against some other form of name,
because these occur quite often and cause little difficulty in practice: so
they would only clutter up the dictionary with spurious warnings.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Ignore apparent clashes which are in fact not troublesome</span><span class="named-paragraph-number">17.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">d</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">; </span><span class="comment-syntax"> both definitions come from the same extension</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Str::eq_wide_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">ede1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">type</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"property"</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">Str::eq_wide_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">ede2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">type</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"property"</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">Str::eq_wide_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">ede1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">type</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"property"</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">Str::eq_wide_string</span><span class="plain-syntax">(</span><span class="identifier-syntax">ede2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">type</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"property"</span><span class="plain-syntax">))) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="7-dct.html#SP17">&#167;17</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP17_2" class="paragraph-anchor"></a><b>&#167;17.2.  </b>If we can find the righthand extension on the righthand side of any KEC
in the list, then the clash is not a new one: we simply increment the number
of definition pairs clashing between the left and right extensions, and
return. (Thus forgetting what the actual definitions causing the present
clash were: we don't need them, as we already have an example of the
definitions clashing between the two.) But if we can't find righthand
extension anywhere in the list, we must add the new pair of definitions:
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Search list of KECs deriving from the same left extension as this clash</span><span class="named-paragraph-number">17.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">kec</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-wrk.html#SP9" class="function-link"><span class="function-syntax">Works::match</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rightx</span><span class="plain-syntax">, </span><span class="identifier-syntax">kec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">rightx</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ede_work</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">kec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">number_clashes</span><span class="plain-syntax">++; </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">kec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">kec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><a href="7-dct.html#SP16" class="function-link"><span class="function-syntax">ExtensionDictionary::new_clash</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">left</span><span class="plain-syntax">, </span><span class="identifier-syntax">right</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">kec</span><span class="plain-syntax"> = </span><span class="identifier-syntax">kec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="7-dct.html#SP17">&#167;17</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18.  </b>The above arrangement was designed to make it easy to print out the
clashes in a concise, human-readable way, which is what we now do.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ExtensionDictionary::list_known_extension_clashes</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">ExtensionDictionary::list_known_extension_clashes</span></span>:<br/><a href="7-dct.html#SP14">&#167;14</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">known_extension_clash</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kec</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">NUMBER_CREATED</span><span class="plain-syntax">(</span><span class="reserved-syntax">known_extension_clash</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="7-dct.html#SP18_1" class="named-paragraph-link"><span class="named-paragraph">Write the headnote about what extension clashes mean</span><span class="named-paragraph-number">18.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER</span><span class="plain-syntax">(</span><span class="identifier-syntax">kec</span><span class="plain-syntax">, </span><span class="reserved-syntax">known_extension_clash</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">kec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_known</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="named-paragraph-container code-font"><a href="7-dct.html#SP18_2" class="named-paragraph-link"><span class="named-paragraph">Write a paragraph about extensions clashing with the lefthand one here</span><span class="named-paragraph-number">18.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP18_1" class="paragraph-anchor"></a><b>&#167;18.1.  </b>Not the end of the world! Extension clashes are not an error condition: they
are, if anything, a sign of life and activity.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Write the headnote about what extension clashes mean</span><span class="named-paragraph-number">18.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">HTML_OPEN</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;b&gt;Clashes found.&lt;/b&gt; The dictionary above shows that some "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"extensions make incompatible definitions of the same words or phrases. "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"When two extensions disagree like this, it is not necessarily a bad "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"sign (they might simply be two ways to approach the same problem), "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"but in general it means that it may not be safe to use both "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"extensions at the same time. The following list shows some potential "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"clashes."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="7-dct.html#SP18">&#167;18</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP18_2" class="paragraph-anchor"></a><b>&#167;18.2.  </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Write a paragraph about extensions clashing with the lefthand one here</span><span class="named-paragraph-number">18.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">known_extension_clash</span><span class="plain-syntax"> *</span><span class="identifier-syntax">example</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HTML_OPEN</span><span class="plain-syntax">(</span><span class="string-syntax">"b"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-wrk.html#SP6" class="function-link"><span class="function-syntax">Works::write_to_HTML_file</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">kec</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">leftx</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ede_work</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"b"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">": "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">example</span><span class="plain-syntax"> = </span><span class="identifier-syntax">kec</span><span class="plain-syntax">; </span><span class="identifier-syntax">example</span><span class="plain-syntax">; </span><span class="identifier-syntax">example</span><span class="plain-syntax"> = </span><span class="identifier-syntax">example</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"clash with "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">HTML_OPEN</span><span class="plain-syntax">(</span><span class="string-syntax">"b"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-wrk.html#SP6" class="function-link"><span class="function-syntax">Works::write_to_HTML_file</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">example</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">rightx</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ede_work</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"b"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" (on "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">example</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">number_clashes</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%d names, for instance "</span><span class="plain-syntax">, </span><span class="identifier-syntax">example</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">number_clashes</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S)"</span><span class="plain-syntax">, </span><span class="identifier-syntax">example</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">leftx</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">entry_text</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">example</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"; "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">HTML_OPEN</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="7-dct.html#SP18">&#167;18</a>.</li></ul>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="7-tm.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-sm.html">1</a></li><li class="progresschapter"><a href="2-gnr.html">2</a></li><li class="progresschapter"><a href="3-bg.html">3</a></li><li class="progresschapter"><a href="4-em.html">4</a></li><li class="progresschapter"><a href="5-es.html">5</a></li><li class="progresschapter"><a href="6-st.html">6</a></li><li class="progresscurrentchapter">7</li><li class="progresssection"><a href="7-tm.html">tm</a></li><li class="progresscurrent">dct</li><li class="progresssection"><a href="7-cns.html">cns</a></li><li class="progresssection"><a href="7-ip.html">ip</a></li><li class="progresssection"><a href="7-ip2.html">ip2</a></li><li class="progresssection"><a href="7-tr.html">tr</a></li><li class="progressnext"><a href="7-cns.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->

		</main>
	</body>
</html>

